import base64
import logging
import threading
import time
import cv2
from tools.constant.redis_keys import *
from tools.utils.logging_setting import set_logging
from tools.utils.redis_client import redis_client_instance

set_logging()

redis_client = redis_client_instance()
def process_image(camera_name, rtsp_url):
    loop_counter = 0
    try:
        cap = cv2.VideoCapture(rtsp_url)

        if not cap.isOpened():
            logging.info(f"Failed to open video stream for {camera_name}")
            cap.release()
            cv2.destroyAllWindows()
            exit()
        fps = cap.get(cv2.CAP_PROP_FPS)
        logging.info((f"Video FPS for {camera_name}: {fps}"))
        fps_loop=0
    except Exception as e:
        logging.error(e)
        exit()
    while loop_counter<10000:
        if redis_client.get(REDIS_CAMERA_THREAD_FLAG_PREFIX+camera_name) == b'0':
            logging.info(f"{camera_name} is offline")
            redis_client.set(REDIS_CAMERA_THREAD_FLAG_PREFIX+camera_name,b'1')
            break
        try:
            #redis_client.delete(REDIS_CAMERA_THREAD_FLAG_PREFIX+camera_name)
            image_byte = b''
            ret, frame = cap.read()
            if not ret:
                logging.debug(f"Failed to read frame for {camera_name}")
                # image_byte = b''
            else:
                ret_img, image_data = cv2.imencode('.jpg', frame)
                # 按秒保存帧
                # 将图片转换为字节数据
                ret_img, image_data = cv2.imencode('.jpg', frame)
                if not ret_img:
                    logging.debug(f"Failed to encode frame for {camera_name}")
                    # image_byte= b''
                    continue
                else:
                    image_byte = image_data.tobytes()
            fps_loop = fps_loop+1
            ts = int(time.time())
            timestamp = ts * 100 + fps_loop%fps
            if fps_loop > 500:
                fps_loop = fps_loop -500
            redis_key = REDIS_CAMERA_FRAME_KEY_PREFIX + camera_name
            redis_client.zadd(redis_key, {image_byte: timestamp})
            # 获取列表的当前长度
            list_length = redis_client.zcard(REDIS_CAMERA_FRAME_KEY_PREFIX+camera_name)
            if list_length > fps * 5:
                oldest_member = redis_client.zrange(redis_key, 0, 0, withscores=True)[0][0]
                # 从 ZSet 中移除最旧的条目
                redis_client.zrem(redis_key, oldest_member)
        except Exception as e:
            logging.error(f"Error processing frame for {camera_name}: {e}")
        loop_counter = loop_counter+1
    cap.release()
    cv2.destroyAllWindows()
    logging.info(f"{camera_name} is exiting")
    exit()


all_thread_list = []
all_camera_list = []


def check_thead_status():
    red = redis_client_instance()
    while True:
        camera_info = red.hgetall(REDIS_CAMERA_INFO_KEY)
        # 当前运行线程
        current_list = []
        for k, v in camera_info.items():
            camera_name = k.decode('utf-8')
            current_list.append(k.decode('utf-8') + "-thread")
            #如果有新的，增加进去
            if k.decode('utf-8') + "-thread" in all_camera_list:
                continue
            else:
                all_camera_list.append(k.decode('utf-8') + "-thread")
                thread = threading.Thread(target=process_image, args=(k.decode('utf-8'), v.decode('utf-8').replace("\"",'')),
                                          name=k.decode('utf-8') + "-thread")
                all_thread_list.append(thread)
                logging.debug(f"线程启动中 {k.decode('utf-8')}")
                thread.start()
        # 检查存活
        for t in all_thread_list:
            if t.name not in current_list:
                red.set(REDIS_CAMERA_THREAD_FLAG_PREFIX+t.name[:-len("-thread")], b'0')
                red.delete(REDIS_CAMERA_FRAME_KEY_PREFIX+t.name[:-len("-thread")])
                continue
            if not t.is_alive():
                all_camera_list.remove(t.name)
                all_thread_list.remove(t)
            logging.debug("线程%s状态-》%s " % (t.name, t.is_alive()))
        if red.get(RTSP_SERVER_STATUS) == b'0':
            logging.info("check_thead_status is offline")
            for t in all_thread_list:
                red.set(REDIS_CAMERA_THREAD_FLAG_PREFIX + camera_name, b'0')
            red.delete(RTSP_SERVER_STATUS)
            exit()
        else:
            time.sleep(5)


def read_camera():
    redis_client = redis_client_instance()
    camera_info = redis_client.hgetall('camera_info')
    hash_data = {k.decode('utf-8'): v.decode('utf-8').replace("\"",'') for k, v in camera_info.items()}
    return hash_data

def print_all_threads():
    while True:
        # 获取当前所有活动的线程
        active_threads = threading.enumerate()
        print("--线程数量为 %d " % len(active_threads))
        time.sleep(1)


if __name__ == '__main__':
    # threading.Thread(target=print_all_threads).start()
    check_thead_status()
    # process_image("3","rtmp://admin:cctv12345@172.16.10.240:1935/live/3")
    # threading.Thread(target=print_all_threads).start()

